#include "Camera.h"
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <cmath>
#include "KeyManager.h"

Camera::Camera() : LookSpeed(0.005f), MoveSpeed(0.05f), 
	PitchClampInRadian(1.3962f), YawClampInRadian(6.2831f),
	m_MoveOnlyOnHorizontalPlane(false)
{
	m_Position = glm::vec3(0.0f, 2.0f, 5.0f);
	m_AngleX = 3.14f;
	m_AngleY = 0;
}

Camera::Camera(glm::vec3 position) : LookSpeed(0.005f), MoveSpeed(0.05f), 
	PitchClampInRadian(1.3962f), YawClampInRadian(6.2831f),
	m_MoveOnlyOnHorizontalPlane(false)
{
	m_Position = position;
	m_AngleX = 3.14f;
	m_AngleY = 0;
}

Camera::~Camera()
{
}

void Camera::update()
{
	float cameraY = m_Position.y;

	int midX = 180;
	int midY = 120;

	SDL_ShowCursor(SDL_DISABLE);

	int curX;
	int curY;

	SDL_GetMouseState(&curX, &curY);

	m_AngleX -= (curX - midX) * LookSpeed;
	m_AngleY -= (curY - midY) * LookSpeed;

	SDL_WarpMouse(midX, midY);

	if (m_AngleX > YawClampInRadian)
		m_AngleX -= YawClampInRadian;

	if (m_AngleX < 0.0)
		m_AngleX += YawClampInRadian;

	if(m_AngleY > PitchClampInRadian)
		m_AngleY = PitchClampInRadian;

	if(m_AngleY < -PitchClampInRadian)
		m_AngleY = -PitchClampInRadian;

	// Get forward vector
	m_Forward = glm::vec3(
		cos(m_AngleY) * sin(m_AngleX), 
		sin(m_AngleY),
		cos(m_AngleY) * cos(m_AngleX)
		);

	// Get right vector
	m_Right = glm::vec3(
		sin(m_AngleX - 3.14f/2.0f), 
		0,
		cos(m_AngleX - 3.14f/2.0f)
		);

	// Get up vector
	m_Up = glm::cross( m_Right, m_Forward );

	if (KeyManager::get()->isKeyDown(KEY_UP)) {
		m_Position += m_Forward * MoveSpeed;
	} else if (KeyManager::get()->isKeyDown(KEY_DOWN)) {
		m_Position -= m_Forward * MoveSpeed;
	}
	if (KeyManager::get()->isKeyDown(KEY_LEFT)) {
		m_Position -= m_Right * MoveSpeed;
	} else if (KeyManager::get()->isKeyDown(KEY_RIGHT)) {
		m_Position += m_Right * MoveSpeed;
	}

	if (m_MoveOnlyOnHorizontalPlane)
	{
		m_Position.y = cameraY;
	}
	m_ViewMatrix = glm::lookAt(m_Position, m_Position + m_Forward, m_Up);
	glMultMatrixf(&m_ViewMatrix[0][0]);
}

void Camera::setMoveOnlyOnHorizontalPlane(bool flag)
{
	m_MoveOnlyOnHorizontalPlane = flag;
}

glm::vec3 Camera::getPosition()
{
	return m_Position;
}

glm::vec3 Camera::getForward()
{
	return glm::normalize(m_Forward);
}